<template>
    <div class="DictionaryUI">
        <div class="see" v-if="isSee">
            <div v-if="data.multiple == 2 && modelValue" class="multiple-value">
                <div v-if="multiple">
                    <div v-if="showBorder">
                        <div class="value-item" v-for="(item,index) in modelValue" :key="index" :style="`color:${dict.getTxtColor(data,item)};background-color:${dict.getBackgroundColor(data,item)};`">
                            {{ dict.getLbel(data, item) }}
                        </div>
                    </div>
                    <div v-else class="value-item2">
                        <div v-if="modelValue.length>0" :style="`color:${dict.getTxtColor(data,modelValue[0])};`">
                            {{ dict.getLbel(data, modelValue[0]) }}
                        </div>
                        <div v-for="(item,index) in getOneNexts(modelValue)" :key="index" :style="`color:${dict.getTxtColor(data,item)};`">
                            {{ separator }}{{ dict.getLbel(data, item) }}
                        </div>
                    </div>
                </div>
                <div v-else>
                    <div v-if="showBorder">
                        <div class="value-item" :style="`color:${dict.getTxtColor(data,modelValue)};background-color:${dict.getBackgroundColor(data,modelValue)};`">
                            {{ dict.getLbel(data, modelValue) }}
                        </div>
                    </div>
                    <div v-else>
                        <div class="value-item2" :style="`color:${dict.getTxtColor(data,modelValue)};`">
                            {{ dict.getLbel(data, modelValue) }}
                        </div>
                    </div>
                </div>
            </div>
            <div v-if="data.multiple == 1 && modelValue==dict.getOneValue(data)" class="one-value">
                <div class="value-item" :style="`color:${data.value.txt_color};background-color:${data.value.background_color};`">
                    {{ dict.getOneLabel(data, modelValue) }}
                </div>
            </div>
        </div>
        <div v-else>
            <div class="select" v-if="data.multiple == 2">
                <div v-if="type == 'select'" class="select-ex">
                    <div v-if="showPend" class="prepend">
                        <slot name="prepend"></slot>
                    </div>
                    <el-select v-model="selectValue" :placeholder="placeholder" :disabled="disabled" :clearable="clearable" :multiple="multiple" @change="change" style="width:100%;">
                        <el-option v-for="(item) in selectItem" :key="item.value" :label="item.label" :value="item.value">
                        </el-option>
                    </el-select>
                    <div v-if="showPend" class="append">
                        <slot name="append"></slot>
                    </div>
                </div>
                <div v-if="type == 'box'">
                    <div v-if="multiple">
                        <el-checkbox-group v-model="selectValue" @change="change" :disabled="disabled">
                            <el-checkbox v-for="(item,index) in selectItem" :key="index" :label="item.value">
                                {{ item.label }}
                            </el-checkbox>
                        </el-checkbox-group>
                    </div>
                    <div v-else>
                        <el-radio-group v-model="selectValue" @change="change" :disabled="disabled">
                            <el-radio v-for="(item,index) in selectItem" :key="index" :label="item.value">
                                {{ item.label }}
                            </el-radio>
                        </el-radio-group>
                    </div>
                </div>
            </div>
            <div v-if="data.multiple == 1">
                <div class="input select-ex" v-if="type == 'select'">
                    <div v-if="showPend" class="prepend">
                        <slot name="prepend"></slot>
                    </div>
                    <div>
                        <el-select v-model="selectValue" :placeholder="placeholder" :disabled="disabled" :clearable="clearable" @change="change" style="width:100%;">
                            <el-option v-for="(item,index) in selectItem" :key="index" :label="item.label" :value="item.value">
                            </el-option>
                        </el-select>
                    </div>
                    <div v-if="showPend" class="append">
                        <slot name="append"></slot>
                    </div>
                </div>
                <div v-if="type == 'box'">
                    <PRadioBox v-model="selectValue" :disabled="disabled" :label="data.value.label" :value="dict.getOneValue(data)" @change="change"/>
                </div>
            </div>
        </div>
    </div>
</template>

<script lang="ts">
import setCssVal from "@/lib/setCssVal";
import utils from "@/lib/utils";
import {defineComponent, onMounted, reactive, toRefs, watch} from "vue";
import {useStore} from "vuex";
import PRadioBox from "../PRadioBox.vue";
import dict, {Dict, DictVal, defaultDict} from "./dictionary";

/**
 * state 数据类型
 */
interface IState {
    /**
     * 字典数据
     */
    data: Dict;
    /**
     * 选择数据
     */
    selectValue: any;
    /**
     * 选择项
     */
    selectItem: any[];
}

export default defineComponent({
    name: "DictionaryUI",
    components: {PRadioBox},
    props: {
        modelValue: {
            type: [Array, String, Number],
            default: ""
        },
        type: { // 组件类型 select=选择框  box=如果多选是多选框，如果单选就是单选框
            type: String,
            default: "select"
        },
        onlyKey: { // 唯一标识
            type: String,
            default: ""
        },
        placeholder: { // 提示
            type: String,
            default: "请选择"
        },
        multiple: { // 是否多选
            type: Boolean,
            default: false
        },
        isSys: { // 是否系统设置
            type: Boolean,
            default: false
        },
        disabled: { // 是否禁用
            type: Boolean,
            default: false
        },
        clearable: { // 是否显示清楚图标
            type: Boolean,
            default: true
        },
        isSee: { // 是否查看模式
            type: Boolean,
            default: false
        },
        showPend: { // 是否显示前置和后置内容
            type: Boolean,
            default: false
        },
        // 是否显示边框
        showBorder: {
            type: Boolean,
            default: false
        },
        // 分隔符
        separator: {
            type: String,
            default: "、"
        }
    },
    emits: ["update:modelValue", "change"],
    setup(props, {emit}) {
        const store = useStore();
        const {UIAuth, bodySize} = toRefs(store.state);
        const state = reactive<IState>({
            data: defaultDict(),
            selectItem: [],
            selectValue: [],
        });

        function initDict(val: Dict) {
            state.data = val;
            if (!props.isSee) {
                state.selectItem = [];
                if (val.multiple === 1) {
                    state.selectItem.push({label: val.value.label, value: dict.getOneValue(val)});
                } else if (val.multiple === 2) {
                    val.values.forEach((item) => state.selectItem.push({
                        label: item.label,
                        value: dict.getDataTypeValue(val.int_type, item)
                    }));
                }
            }
            initValue();
        }

        function getDict() {
            if (!utils.empty(props.onlyKey)) {
                if (props.isSys) {
                    initDict(dict.getSys(props.onlyKey))
                } else {
                    initDict(dict.get(props.onlyKey))
                }
            }
        }

        watch(() => props.modelValue, (newValue) => {
            initValue();
        });
        watch(() => props.onlyKey, (newValue, oldValue) => getDict());
        watch(() => props.showPend, (newValue, oldValue) => {
            if (newValue) {
                setCssVal.setCssVal("--dictionaryui-select-ex-radius", "0");
            } else {
                setCssVal.setCssVal("--dictionaryui-select-ex-radius", "4px");
            }
        });

        function initValue() {
            if (!utils.empty(props.modelValue)) {
                if (state.data.multiple === 1 && props.type === "box") {
                    state.selectValue = props.modelValue;
                } else {
                    state.selectValue = props.modelValue;
                }
                if (state.data.int_type == 1) {
                    // a.toString()
                    if (props.multiple && state.selectValue.length > 0) {
                        state.selectValue.forEach((item: any) => {
                            item = item.toString();
                        });
                    } else {
                        state.selectValue = state.selectValue.toString();
                    }
                } else if (state.data.int_type == 2) {
                    if (props.multiple && state.selectValue.length > 0) {
                        state.selectValue.forEach((item: any) => {
                            item = parseInt(item, 0);
                        });
                    } else {
                        state.selectValue = parseInt(state.selectValue, 0);
                    }
                } else if (state.data.int_type == 3) {
                    if (props.multiple && state.selectValue.length > 0) {
                        state.selectValue.forEach((item: any) => {
                            item = parseFloat(item);
                        });
                    } else {
                        state.selectValue = parseFloat(state.selectValue);
                    }
                }
            }
        }

        function change(e: any) {
            emit("update:modelValue", e);
            let tem = {label: "", value: -1};
            for (const item of state.selectItem) {
                if (item.value == e) {
                    tem = utils.CopyNewObject(item);
                }
            }
            emit("change", tem);
        }

        function getOneNexts(val: any[] = []) {
            const resArr: any = [];
            if (val && val.length > 1) {
                val.forEach((item, index) => {
                    if (index > 0) {
                        resArr.push(item);
                    }
                });
            }
            return resArr;
        }

        onMounted(() => {
            getDict();
            initValue();
            if (props.showPend) {
                setCssVal.setCssVal("--dictionaryui-select-ex-radius", "0");
            } else {
                setCssVal.setCssVal("--dictionaryui-select-ex-radius", "4px");
            }
        });
        return {
            UIAuth,
            bodySize,
            ...toRefs(state),
            dict,
            change,
            getOneNexts
        };
    },
});
</script>

<style scoped lang="scss">
.DictionaryUI {
    //.see {}
    .multiple-value {
        display: flex;
        align-items: center;
        flex-wrap: wrap;

        & > div {
            display: flex;
            align-items: center;
        }
    }

    .value-item2 {
        display: flex;
        align-items: center;
        justify-content: center;
        flex-wrap: wrap;
    }

    .one-value {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
    }

    .value-item {
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 12px;
        padding: 3px 5px;
        border-radius: 4px;
        margin: 3px;
    }

    .select-ex {
        display: flex;
        align-items: center;

        & > div {
            word-break: keep-all; /* 不换行 */
            white-space: nowrap; /* 不换行 */
        }

        & > .prepend {
            background-color: #f4f6f9;
            border-radius: 4px;
            border: 1px solid #dcdfe6;
            border-right: none;
            border-top-right-radius: 0;
            border-bottom-right-radius: 0;
            padding: 0 10px;
            color: var(--el-color-info);
            font-size: 12px;
        }

        & > .append {
            background-color: #f4f6f9;
            border: 1px solid #dcdfe6;
            border-radius: 4px;
            border-left: none;
            border-top-left-radius: 0;
            border-bottom-left-radius: 0;
            padding: 0 10px;
            color: var(--el-color-info);
            font-size: 12px;
        }
    }
}
</style>
<style>
.DictionaryUI .select-ex .el-input__inner {
    border-radius: var(--dictionaryui-select-ex-radius);
    height: 34px;
}
</style>
